<?php

namespace App\Service\VendorClient\Shopjianrunji;

use App\Service\Code\Normal;
use App\Service\BaseService;
use App\Model\PssModel\ServiceConfig;
use Service\AppService\IdService;
use App\Service\TaskServer\TaskWorker;

/**
 * 建闰极上游对接
 * @author: hj
 */
class ShopjianrunjiApiClient extends BaseService {
    //供应商编号
    const SUPPLIER_CODE = 'shopjianrunji';

    //配置文件
    private $config = [];

    public function __construct($apiBody = []) {
        $this->config = $apiBody;
    }

    /**
     * 创建订单
     * @param array $params
     * @return array
     */
    public function createOrder($param = []) {
        if (empty($param['supplierOrder']) || empty($param['orderGoods']) || empty($param['order']) || empty($param['binfo'])) {
            return Normal::returnCode(Normal::FAIL, "except param supplierOrder or orderGoods or order or binfo");
        }
        $orderInfo = $param['supplierOrder'];
        $goodsList = $param['orderGoods'];
        $order     = $param['order'];
        $binfo     = $param['binfo'];
        $order_sn  = $orderInfo['supplier_dsn'];
        //订单时间
        $order_time = $orderInfo['cd'] ? date('Y-m-d H:i:s', $orderInfo['cd']) : date('Y-m-d H:i:s', time());
        //支付时间
        $pay_time = isset($order['payTime']) && !empty($order['payTime']) ? date('Y-m-d H:i:s', $order['payTime']) : date('Y-m-d H:i:s', time());
        //运费分摊
        $deliver_money = $orderInfo['deliver_money'];
        //优惠
        $discount_money = $orderInfo['discount_money'];
        //下单支付的时候支付信息
        $apply_extends = @json_decode($orderInfo['apply_extends'], true);
        //用户实际支付金额
        $real_total_money = $orderInfo['real_total_money'];
        //支付公司和电商平台
        $payCommanyCode = isset($apply_extends['payCommanyCode']) && !empty($apply_extends['payCommanyCode']) ? $apply_extends['payCommanyCode'] : '';
        $payCommanyCode = isset($order['payCommanyCode']) && !empty($order['payCommanyCode']) ? $order['payCommanyCode'] : $payCommanyCode;
        $payCommanyName = isset($apply_extends['payCommanyName']) && !empty($apply_extends['payCommanyName']) ? $apply_extends['payCommanyName'] : '';
        $payCommanyName = isset($order['payCommanyName']) && !empty($order['payCommanyName']) ? $order['payCommanyName'] : $payCommanyName;
        try {
            $payWay = ServiceConfig::instance()->getConfigByEventsValue(self::SUPPLIER_CODE, ServiceConfig::TYPE_PAY, $payCommanyName);
        } catch (\Throwable $th) {
            return Normal::returnCode(Normal::FAIL, "支付方式获取异常：【{$th->getMessage()}】");
        }
        if (empty($payWay)) {
            return Normal::returnCode(Normal::FAIL, "支付公司：【{$payCommanyName}】未映射，请联系管理员处理");
        }
        $paySerial      = isset($apply_extends['paySerial']) && !empty($apply_extends['paySerial']) ? $apply_extends['paySerial'] : '';
        $paySerial      = isset($order['paySerial']) && !empty($order['paySerial']) ? $order['paySerial'] : $paySerial;
        $enterpriseNum  = isset($apply_extends['enterpriseNum']) && !empty($apply_extends['enterpriseNum']) ? $apply_extends['enterpriseNum'] : '';
        $enterpriseNum  = isset($order['enterpriseNum']) && !empty($order['enterpriseNum']) ? $order['enterpriseNum'] : $enterpriseNum;
        $enterpriseName = isset($apply_extends['enterpriseName']) && !empty($apply_extends['enterpriseName']) ? $apply_extends['enterpriseName'] : '';
        $enterpriseName = isset($order['enterpriseName']) && !empty($order['enterpriseName']) ? $order['enterpriseName'] : $enterpriseName;

        //获取下单商品信息
        $palceOrderGoods    = [];
        $totalGoodsMoney    = '0.00';
        $goodsTotalMoney    = '0.00';
        $goodsTotalMoneyNot = '0.00';
        $wayTaxFee          = '0.00';
        $goodsWeight        = '0.00';
        foreach ($goodsList as $key => $item) {
            $tax_rate         = bcadd('1', (string)$item['tax_rate'], 4);
            $price            = $item['price'];
            $spec_num         = $item['spec_num'];
            $quantity         = $item['quantity'];
            $supplier_skucode = $item['supplier_skucode'];
            $goods_type       = $item['goods_type'];
            $weight           = $item['weight'] ? bcdiv((string)($item['weight']), '1000', 2) : '0';
            $goodsWeight      = bcadd($goodsWeight, $weight, 2);
            //实际购买数量(下单数量 X 起售数量)
            $buyAcount = $spec_num * $quantity;
            if ($key == 0) {
                $singleDeliveryMoney = bcdiv((string)$deliver_money, (string)$quantity, 3);
                $singleDeliveryMoney = bcmul((string)$singleDeliveryMoney, (string)100, 1);
                $singleDeliveryMoney = bcdiv((string)ceil($singleDeliveryMoney), (string)100, 2);
                $price               = bcadd((string)$price, (string)$singleDeliveryMoney, 2);
            }
            //单个商品价格
            $singleGoodsPrice = bcdiv((string)$price, (string)$spec_num, 3);
            $singleGoodsPrice = ceil(bcmul((string)$singleGoodsPrice, (string)'100', 1));
            $singleGoodsPrice = bcdiv((string)$singleGoodsPrice, '100', 2);
            $totalGoods       = bcmul((string)$singleGoodsPrice, (string)$buyAcount, 2);

            //含税税率
            $tax_rate = bcadd('1', (string)$item['tax_rate'], 4);
            //不含税价格
            $not_tax_price = bcdiv((string)$singleGoodsPrice, $tax_rate, 3);
            //echo "含税单价:".$singleGoodsPrice."含税税率:".$tax_rate."不含税价格：".$not_tax_price;
            $not_tax_price = ceil(bcmul((string)$not_tax_price, '100', 1));
            // echo "含税税率:".$tax_rate."不含税价格：".$not_tax_price;
            $not_tax_price = bcdiv((string)$not_tax_price, '100', 2);

            //不含税总价
            $goodsTotalPrice = bcmul((string)$not_tax_price, (string)$buyAcount, 2);

            //税金
            $singleGoodsTax = bcsub((string)$singleGoodsPrice, (string)$not_tax_price, 3);
            $taxAll         = bcmul($singleGoodsTax, (string)$buyAcount, 2);
            //不含税总金额
            $goodsTotalMoneyNot = bcadd((string)$goodsTotalMoneyNot, $goodsTotalPrice, 2);
            //含税总金额
            $goodsTotalMoney = bcadd((string)$goodsTotalMoney, $totalGoods, 2);
            //总税费
            $wayTaxFee = bcadd((string)$wayTaxFee, $taxAll, 2);
            //下单商品组
            $goodsInfo = [
                "productNumberCode" => trim($item['supplier_skucode']),//"商品货号（必填）",
                // "productBarCode" => "商品条码（非必填，未填写时，使用商品基本信息中的条码申报海关；填写后，使用此处填写的条码申报海关）",
                "productNumberName" => $item['goods_name'],//"商品名称（必填）",
                "outstoreNumber"    => (int)$buyAcount,//"数量（必填）",
                "price"             => $not_tax_price,//"单价（必填，人民币，填税前价格，以此单价推送海关） 不含税单价"
            ];

            $palceOrderGoods[] = $goodsInfo;
        }
        $couponFee  = $goodsTotalMoney > $orderInfo['real_total_money'] ? bcsub($goodsTotalMoney, $orderInfo['real_total_money'], 2) : '0.00';
        $firstGoods = reset($goodsList);
        if (!in_array($firstGoods['goods_type'], ['1', '2'])) {
            return Normal::returnCode(Normal::FAIL, "当前业务模式只支持跨境保税和跨境直邮【{$firstGoods['goods_type']}】");
        }
        //商品类型（0-一般贸易，1-保税商品，2-海外直邮, 3海外购）
        $tradeMode    = $firstGoods['goods_type'] == 1 ? 1210 : 9610;
        $requestParam = [
            "request" => [
                "kjCustomerOutstore" => [
                    "tradeMode"             => $tradeMode,//"业务模式（9610=跨境直邮，1210=跨境保税）",
                    "saleOrderCode"         => $order_sn,//"订单号（必填）",
                    "flowno"                => $order_sn,//"支付订单号",
                    "orderTime"             => $order_time,//"下单时间（必填：2021-01-18 14:21:21）",
                    "payTime"               => $pay_time,//"支付时间（必填：2021-01-18 14:21:21）",
                    "dealerShopName"        => $this->config['dealerShopName'],//"店铺名称（必填）",
                    "postFee"               => '0.00',//"运费",
                    "insuranceFee"          => '0.00',//"保价费",
                    "tariffAmount"          => 0,//"关税（必填，目前跨境=0）",
                    "addedValueTaxAmount"   => '0.00',//"增值税（必填）",
                    "consumptionDutyAmount" => $wayTaxFee,//"消费税（必填）",
                    "taxAmount"             => $wayTaxFee,//"合计税费（必填）",
                    "disAmount"             => $couponFee,//"优惠金额",
                    "buyerPayment"          => $orderInfo['real_total_money'],//"实付金额（必填）",
                    "grossWeight"           => $goodsWeight,//"商品毛重（必填）kg",
                    "buyerAccount"          => $orderInfo['buyer_phone'],//"买家账号（必填）",
                    "buyerIdNumber"         => $orderInfo['buyer_idcard'],//"订购人身份证号（必填）",
                    "buyerName"             => $orderInfo['buyer_realname'],//"订购人姓名（必填）",
                    "paymentMethodName"     => $payWay,//"支付方式（必填））",
                    "paymentNo"             => $paySerial,//"支付单号（必填）",
                    "receiverName"          => $orderInfo['receive_name'],//"收件人（必填）",
                    "receiverPhone"         => $orderInfo['recveive_phone'],//"联系电话（必填）",
                    "province"              => $orderInfo['province'],//"省（必填）",
                    "city"                  => $orderInfo['city'],//"市（必填）",
                    "district"              => $orderInfo['district'],//"区（必填）",
                    "receiverAddress"       => $orderInfo['receive_address'],//"收件人地址（必填，不含省、市、区）",
                    // "logisticsInterfaceName" => "快递接口名（非必填，不指定则使用店铺默认快递）",
                    "remark"                => $orderInfo['order_remark'] ?? '',//"备注信息",
                    // "promotionList" => [
                    //     "promotion" => [
                    //         "promotionAmount" => "优惠金额",
                    //         "promotionRemark" => "优惠信息说明"
                    //     ]
                    // ],
                    "detailList"            => $palceOrderGoods
                ]
            ]
        ];
        $xmlStr       = $this->arrayToXml($requestParam, 'detail');
        $data         = [
            'method' => 'createOrder',
            'data'   => base64_encode($xmlStr),
        ];
        return $this->execute($data);
    }

    /**
     * 订单取消
     * @param array $params
     * @return array
     */
    public function cancelOrder($params = []) {
        $requestParam = [
            "request" => [
                "kjCustomerOutstore" => [
                    'saleOrderCode' => $params['supplierOrder']['supplier_dsn']
                ]
            ]
        ];
        $xmlStr       = $this->arrayToXml($requestParam);
        $data         = [
            'method' => 'cancelOrder',
            'data'   => base64_encode($xmlStr),
        ];
        return $this->execute($data);
    }

    /**
     * 数组转xml
     * @param $data
     * @param string $multiKey
     * @return string
     */
    public function arrayToXml($data, $multiKey = 'detail') {
        $str = "";
        foreach ($data as $key => $val) {
            if (is_array($val)) {
                if (is_numeric($key)) {
                    $key = $multiKey; // 为数字键名添加前缀以符合XML的命名规则
                }
                $child = $this->arrayToXml($val, $multiKey);
                $str   .= "<$key>$child</$key>";
            } else {
                $str .= "<$key>$val</$key>";
            }
        }
        return $str;
    }

    /**
     * xml转数组
     * @param string $xml
     * @return array
     */
    public function xmlToArray(string $xml) {
        return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    }

    /**
     * 签名
     * @param $data
     * @return string
     */
    public function sign($data) {
        $str = $data['msgData'] . $this->config['userCode'] . $this->config['privateKey'];
        return md5($str);
    }

    /**
     * CURL请求
     * @param $params
     * @return array
     */
    public function execute($param = []) {
        if (!isset($this->config[$param['method']])) {
            return Normal::returnCode(Normal::FAIL, "请求路由未设置");
        }
        if (empty($param['data'])) {
            return Normal::returnCode(Normal::FAIL, "数据不能为空");
        }
        $url = $this->config['baseUrl'];
        if (empty($url)) {
            return Normal::returnCode(Normal::FAIL, "接口地址不能为空");
        }
        $pushData              = [
            'msgType'  => $this->config[$param['method']],
            'userCode' => $this->config['userCode'],
            'msgId'    => uuid4(),
            'msgData'  => $param['data'],
        ];
        $pushData['msgDigest'] = $this->sign($pushData);
        $parameter             = [
            [
                'tag'    => self::SUPPLIER_CODE . '_' . $param['method'],
                'uid'    => IdService::instance()->getOtherID(),
                'url'    => $url,
                'data'   => $pushData,
                'method' => 'post',
                'format' => 'json',
                'header' => [],
            ],
        ];
        $resTask               = TaskWorker::instance()->addTask($parameter);
        $resTask               = current($resTask);
        $result                = $resTask['response']['result'];
        $result                = $this->xmlToArray($result);
        if (isset($result['code']) && $result['code'] == 0) {
            return Normal::returnCode(Normal::SUC, "请求成功", $result);
        } else {
            $msg = $result['message'] ?? '请求失败';
            return Normal::returnCode(Normal::FAIL, $msg, $result);
        }
    }
}